//面板的功能，主要实现面板元素的排序，位置互换
import { fabric } from 'fabric'
import EventEmitter from './EventEmitter.class.js'
import { reactive } from 'vue'
import guid from '@/libs/guid.js'
export default class Basic extends EventEmitter {
  static caches = []
  constructor(options) {
    super()
    this.options = options
    this.list = reactive([])
    this.component = options.component
    this.data = this.component.toJSON()
    this.config = options.config || {}
    this.component.guid = this.guid = guid()
    this.parent = null
    Basic.caches[this.guid] = this
  }
  /**
   * 交换元素
   *
   * @param {} item
   * @param {} distance
   * @param {} swapIndex
   */
  move(item, distance = 0, swapIndex = -1) {
    let index = this.list.indexOf(item)
    if (index > -1) {
      if (swapIndex == -1) swapIndex = index + distance
      let swapItem = this.list[swapIndex]
      let swapObject = this.component._objects[swapIndex]
      if (swapItem) {
        this.list[swapIndex] = item
        this.list[index] = swapItem
        //这里两个都要改变，不好，需要优化，但是顺序决定了渲染顺序了
        this.component._objects[swapIndex] = this.component._objects[index]
        this.component._objects[index] = swapObject
        this.emit('move')
      }
    }
  }
  remove() {
    this.parent.del(this)
  }
  /**
   * 删除子元素
   *
   * @param {} item
   */
  del(item) {
    fabric.util.removeFromArray(this.list, item)
    if (this.component.removeWithUpdate) {
      this.component.removeWithUpdate(item.component)
    } else {
      this.component.remove(item.component)
    }
  }
  /**
   * 移动元素到顶部
   *
   * @param {} item
   */
  moveTop(item) {
    fabric.util.removeFromArray(this.list, item)
    fabric.util.removeFromArray(this.component._objects, item.component)
    this.list.push(item)
    this.component._objects.push(item.component)
    this.emit('move')
  }
  /**
   * 移动元素到底部
   *
   * @param {} item
   */
  moveBottom(item) {
    fabric.util.removeFromArray(this.list, item)
    fabric.util.removeFromArray(this.component._objects, item.component)
    this.list.unshift(item)
    this.component._objects.unshift(item.component)
    this.emit('move')
  }
  /**
   * 插入元素到指定位置
   *
   * @param {} item
   * @param {} index
   */
  insertAt(item, index) {
    this.list.splice(index, 0, item)
    if (this.component.addWithUpdate) {
      this.component.addWithUpdate(item.component)
      if (this.component.canvas) {
        this.component.canvas.renderAll()
      }
    } else {
      this.component.insertAt(item.component, index)
    }
    item.parent = this
    this.emit('move')
  }
  /**
   * 添加元素
   *
   * @param {} item
   */
  add(item) {
    this.insertAt(item, this.list.length)
  }
  /**
   * 查找元素位置
   *
   * @param {} item
   */
  index(item) {
    return this.list.indexOf(item)
  }
  /**
   * 更新自身属性
   *
   * @param {} res
   * @param {} emit
   */
  update(res = {}, emit = true) {
    if (res.src) {
      this.component.setSrc(
        res.src,
        () => {
          this.data = this.component.toJSON()
          if (emit) {
            this.emit('update', this)
            this.refresh()
          }
        },
        this.component.toJSON()
      )
    } else {
      this.component.set(res)
      this.data = this.component.toJSON()
      //console.log(this.data, 'data')
      if (emit) {
        this.emit('update', this)
        this.refresh()
      }
    }
  }
  getRoot() {
    let root = this
    while (root.parent) {
      root = root.parent
    }
    return root
  }
  moveToOther(to_guid) {
    let to = Basic.caches[to_guid]
    if (to) {
      if (this.parent.guid == to_guid) {
        return
      } else {
        let origin_group = this.parent
        let target_group = to
        let origin_index
        //父级可能是根目录
        if (origin_group.parent) {
          origin_index = origin_group.parent.index(origin_group)
        } else {
          origin_index = origin_group.index(this)
        }
        let target_index = target_group.parent.index(target_group)
        this.remove()
        if (origin_index < target_index) {
          to.insertAt(this, 0)
        } else {
          to.add(this)
        }
      }
    } else {
      //分离组
      let root = this.getRoot()
      let origin_index = this.parent.parent.index(this.parent)
      this.remove()
      root.insertAt(this, origin_index)
    }
  }
  resetScale() {
    this.component.scale(1).rotate(0)
    this.refresh()
  }
  refresh() {
    let root = this.getRoot()
    root.canvas.renderAll()
  }
  select() {
    this.component.canvas.setActiveObject(this.component)
    this.refresh()
  }
  discardActive() {
    this.component.canvas.discardActiveObject()
    this.refresh()
  }
}
